fix: eliminate flicker when opening tree window#3313
fix: eliminate flicker when opening tree window#33130ax1 wants to merge 1 commit intonvim-tree:masterfrom
Conversation
Suppress events during the open+reposition to prevent intermediate redraws. Signed-off-by: Alexander Droste <alexander.droste@protonmail.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
alex-courtis
left a comment
There was a problem hiding this comment.
Many thanks for your contribution!
Please can you provide a test case that can demonstrate the problem. I can then validate the fix.
| vim.api.nvim_command("vsp") | ||
| local ei = vim.o.eventignore | ||
| vim.o.eventignore = "all" | ||
| vim.api.nvim_open_win(M.get_bufnr(), true, { |
There was a problem hiding this comment.
What's the reason for this change from vsp?
This code is very fagile and has to handle a lot of edge cases.
There was a problem hiding this comment.
LLM might have not 'known' about it though…
There was a problem hiding this comment.
vim.api.nvim_command("vsp") opens a vsplit showing the current buffer in the new split first and then swapping it after in my understanding. What I'm trying to do here is ignore displaying intermediate steps via local ei = vim.o.eventignore, set the correct buffer from the start vim.api.nvim_open_win(M.get_bufnr(), position the window like before M.reposition_window(), and then finally make the changes visible vim.o.eventignore = ei.
Right now I see a glitch each time I toggle nvim-tree to visible, as in I can see that vsp initially splits the buffer has the content of the current buffer, before it repositions and shows the content of the file tree.
So the repro really only is toggle nvim-tree, not using a float window.
There was a problem hiding this comment.
@gegoune Yeah I've been iterating with on this with Claude, and might be totally possible that some subtleties have been missed. I never really went deep on nvim plugins before but this seemed reasonable as a first iteration.
@alex-courtis Maybe it's possible to keep vsp if we ignore intermediate events local ei = vim.o.eventignore?
There was a problem hiding this comment.
It looks like set_window_options_and_buffer is already temporarily setting eventignore via vim.api.nvim_set_option. Using eventignore is very dangerous and we use it only when we absolutely have to.
I can't see the flicker however I do understand how it occurs. If I comment out set_window_options_and_buffer it does indeed show the current buffer in the tree window.
@alex-courtis Maybe it's possible to keep vsp if we ignore intermediate events local ei = vim.o.eventignore?
I did try wrapping vsp with the eventignore, however that had no effect - the current buffer is still displayed.
Thanks for having a look! I mentioned a flow in the other comment. Let me know if you meant an automated test. |
There was a problem hiding this comment.
I'm really reluctant to
- make this
nvim_open_winchange to open a new window with the tree buffer, as there is already a lot of code to switch the buffer in, that would need to be remediated - add an extremely risky
eventignore, which I'm not convinced is actually helping
This is a very fragile area of code and has broken many times in history, hence we don't make changes unless absolutely necessary.
How about a less risky compromise:
- Use
:vnewso that the window opens with a new empty buffer - Make the new buffer a
help scratch-bufferwithbufhidden=wipe
I'm open to using lua API for 2, however changing 1 from vimscript is just too risky.
| vim.api.nvim_command("vsp") | ||
| local ei = vim.o.eventignore | ||
| vim.o.eventignore = "all" | ||
| vim.api.nvim_open_win(M.get_bufnr(), true, { |
There was a problem hiding this comment.
It looks like set_window_options_and_buffer is already temporarily setting eventignore via vim.api.nvim_set_option. Using eventignore is very dangerous and we use it only when we absolutely have to.
I can't see the flicker however I do understand how it occurs. If I comment out set_window_options_and_buffer it does indeed show the current buffer in the tree window.
@alex-courtis Maybe it's possible to keep vsp if we ignore intermediate events local ei = vim.o.eventignore?
I did try wrapping vsp with the eventignore, however that had no effect - the current buffer is still displayed.
|
Seems like a quite an intricate part of the logic in nvim-tree. Happy to keep this as is to not accidentally disrupt other ppls flow. |
Suppress events during the open+reposition to prevent intermediate redraws.